package com.lemzdo.mail.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lemzdo.common.constant.ProductConstant;
import com.lemzdo.common.utils.PageUtils;
import com.lemzdo.common.utils.Query;
import com.lemzdo.mail.product.dao.AttrAttrgroupRelationDao;
import com.lemzdo.mail.product.dao.AttrDao;
import com.lemzdo.mail.product.dao.AttrGroupDao;
import com.lemzdo.mail.product.entity.AttrAttrgroupRelationEntity;
import com.lemzdo.mail.product.entity.AttrEntity;
import com.lemzdo.mail.product.entity.AttrGroupEntity;
import com.lemzdo.mail.product.service.AttrGroupService;
import com.lemzdo.mail.product.service.AttrService;
import com.lemzdo.mail.product.vo.AttrGroupWithAttrsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private AttrAttrgroupRelationDao relationDao;
    @Autowired
    private AttrDao attrDao;
    @Autowired
    private AttrService attrService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 自定义带id参数的查询功能，规定id为0 代表不选择，返回所有；有id，则根据id，精确返回数据
     *  无论查询所有还是根据id查询  都需要设置模糊查询
     * @param params    逆向工程生成的前端传回来的map参数
     * @param catelogId 自定义传回来的id
     * @return 返回分页数据给前端
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catelogId) {

        //params请求参数中 有一个key 代表检索关键字，还得按照这个关键字检索
        String key = (String) params.get("key");
        //select * from pms_attr_group where catelog_id=? and (attr_group_id=key or attr_group_name like %key%)

        //先根据catelog_id 构造查询条件（类似构造example）
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();

        //判断key 并看情况是否据需构造
        if (!StringUtils.isEmpty(key)) {
            //若key不为空 需要加上key的一些判断 and可以函数式编程风格 在里面构造key的一些判断
            wrapper.and((obj) -> {
                //like表示 %key% 也可以根据模糊查询条件自行决定likeRight 和 likeLeft
                obj.eq("attr_group_id", key).or().like("attr_group_name", key);
            });
        }

        //判断三级分类id
        /*if (catelogId == 0) {
            IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params), wrapper);
            return new PageUtils(page);
        } else {
            //根据三级分类id查询
            //根据判断条件（wrapper）返回结果 封装到page里
            wrapper.eq("catelog_id", catelogId);
            IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params), wrapper);
            return new PageUtils(page);
        }*/

         if (catelogId != 0) {
             //根据三级分类id查询
             //根据判断条件（wrapper）返回结果 封装到page里
             wrapper.eq("catelog_id", catelogId);
        }
        IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params), wrapper);
        return new PageUtils(page);

    }

    /**
     * 根据分组id 获取属性分组里面还没有关联的本分类里面的其他基本属性，方便添加新的关联
     * @param params 分页信息
     * @param attrgroupId 属性分组id
     * @return 分页查询的结果
     */
    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {

        //1、当前分组只能关联 对应分类里面的属性
        //查出当前分组的分类id
        AttrGroupEntity attrGroupEntity = this.getById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId();

        //2、当前分组只能关联 其他分组未引用的属性

        //查询出所有 分类id 对应的分组
        List<AttrGroupEntity> groupEntities = this.baseMapper.selectList(
                new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));

        //查询所有被引用了的属性(通过分组的attrGroupId去关系表找attrId 然后去attr表找这些属性除外的属性)
        //获取attrGroupIds
        List<Long> attrGroupIds = groupEntities.stream().map(AttrGroupEntity::getAttrGroupId)
                .collect(Collectors.toList());
        //获取attrGroupIds对应的关系数据们
        List<AttrAttrgroupRelationEntity> relationEntities = relationDao.selectList(
                new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", attrGroupIds));
        //获取attrIds
        List<Long> attrIds = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());
        //移除掉这些被引用了的属性 也就是三级id符合条件 但是attrId不在 attrIds里面的属性 并且类型是基本属性不是销售属性
        //构造插叙条件 再当参数放入分页
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>()
                .eq("catelog_id", catelogId)
                .eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        //拼接not in attrIds的时候 需要非空判断
        if(attrIds.size() > 0){
            wrapper.notIn("attr_id", attrIds);
        }

        //判断分页参数中的模糊查询关键字key
        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            wrapper.and((w)-> w.eq("attr_id",key).or().like("attr_name",key));
        }
        IPage<AttrEntity> page = attrService.page(new Query<AttrEntity>().getPage(params), wrapper);
        return new PageUtils(page);
    }

    /**
     * 获取分类下所有分组&关联属性
     * @param catelogId 三级分类id
     * @return vos
     */
    @Override
    public List<AttrGroupWithAttrsVo> getAttrGroupWithAttrByCatelogId(Long catelogId) {

        //1、查出三级分类id对应的各个分组 attr_group就有
        List<AttrGroupEntity> attrGroupEntities = this.list(
                new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));

        //2、各个分组分别查出分组下的各个属性 全部赋值到vo里
        List<AttrGroupWithAttrsVo> vos = attrGroupEntities.stream().map(group -> {
            //先赋值基本属性到vo里
            AttrGroupWithAttrsVo vo = new AttrGroupWithAttrsVo();
            BeanUtils.copyProperties(group, vo);
            //再设置 attrs 将该分组下的关联的属性设置到vo里(之前写过 通过分组id找关联属性的方法)
            List<AttrEntity> attrs = attrService.getAttrRelation(vo.getAttrGroupId());
            vo.setAttrs(attrs);
            return vo;
        }).collect(Collectors.toList());

        return vos;
    }
}